﻿<template>
  <div v-if = 'showMD' class = 'md_content'>
    <link rel="stylesheet" href = "/static/editorMd/css/editormd.min.css">
    <link rel="stylesheet" href = "/static/editorMd/examples/css/style.css" />
    <link rel="stylesheet" href = "/static/editorMd/css/editormd.preview.min.css" />
    <div id = 'editorId' v-if = '!disabled'></div>
    <div id = "layout" v-else>
      <div id = "sidebar" :class = "hadToc ? '' : 'sildebarHidden'">
        <div class="markdown-body editormd-preview-container" id = "custom-toc-container">暂无目录</div>
      </div>
      <div id = 'editorId_show' :class = "hadToc ? '' : 'editorId_show_noToc'"></div>
    </div>
    <!-- 上传图片的弹窗 -->
    <Upload-Img :showUploadDialog = 'showUploadDialog' @uploadImgSuccess = 'uploadImgSuccess'
    @giveUploadImg = 'showUploadDialog = false'></Upload-Img>
  </div>
</template>

<script>
import scriptjs from 'scriptjs'
import UploadImg from './UploadImg'
export default {
  components: { UploadImg },
  props: {
    disabled: {
      type: Boolean,
      default: false
    },
    // 默认值
    defaultValue: {
      type: String
    },
    // 初始化的状态
    showMD: {
      type: Boolean
    }
  },
  data () {
    return {
      currentValue: this.defaultValue || null,
      editor: null,
      timer: null,
      initData: '',
      jsLoadOver: false,
      initDataDelay: 0, // 延迟初始化数据时间，单位毫秒
      showUploadDialog: false, // 上传图片的弹窗
      // 判断是否有目录
      hadToc: true,
      defaultConfig: {
        mode: 'gfm',
        width: '100%',
        height: 360,
        delay: 300,
        path: '/static/editorMd/lib/',
        // theme: 'dark',
        // previewTheme: 'dark',
        // editorTheme: 'pastel-on-dark',
        markdown: '', // 默认填充内容
        value: '', // html
        readOnly: false, // 只读模式
        lineWrapping: true, // 编辑框不换行
        codeFold: true, // 代码折叠
        placeholder: '请输入...',
        syncScrolling: true,
        saveHTMLToTextarea: true, // 保存 HTML 到 Textarea
        searchReplace: true,
        watch: true, // 实时预览
        htmlDecode: 'style,script,iframe|on*', // 开启 HTML 标签解析，为了安全性，默认不开启
        toolbar: true, // 工具栏
        toolbarIcons: [
          'undo', 'redo', '|', 'bold', 'del', 'italic', 'quote', 'ucwords', 'uppercase', 'lowercase', '|',
          'h1', 'h2', 'h3', 'h4', 'h5', 'h6', '|',
          'list-ul', 'list-ol', 'hr', '|',
          'link', 'reference-link', 'code', 'preformatted-text', 'code-block', 'table', 'datetime', 'emoji', 'html-entities', 'pagebreak', '|',
          'goto-line', 'watch', 'preview', 'clear', 'search', 'uploadImageIcon'
        ],
        previewCodeHighlight: true, // 预览 HTML 的代码块高亮，默认开启
        emoji: true,
        taskList: true,
        tocm: true, // Using [TOCM]
        tex: true, // 开启科学公式TeX语言支持，默认关闭
        flowChart: true, // 开启流程图支持，默认关闭
        sequenceDiagram: true, // 开启时序/序列图支持，默认关闭,
        dialogLockScreen: false, // 设置弹出层对话框不锁屏，全局通用，默认为true
        dialogShowMask: false, // 设置弹出层对话框显示透明遮罩层，全局通用，默认为true
        dialogDraggable: false, // 设置弹出层对话框不可拖动，全局通用，默认为true
        dialogMaskOpacity: 0.4, // 设置透明遮罩层的透明度，全局通用，默认值为0.1
        dialogMaskBgColor: '#000', // 设置透明遮罩层的背景颜色，全局通用，默认为#fff
        imageUpload: false,
        imageFormats: ['jpg', 'jpeg', 'gif', 'png', 'bmp', 'webp'],
        imageUploadURL: '',
        onload: null,
        toolbarIconsClass: {
          uploadImageIcon: 'fa-picture-o' // 指定一个FontAawsome的图标类
        },
        toolbarHandlers: { // 自定义工具栏按钮的事件处理
          uploadImageIcon: function (cm, icon, cursor, selection) {
            // this.uploadImageMethod()
            // console.log(this)
          }
        },
        lang: {
          toolbar: {
            uploadImageIcon: '上传图片'
          }
        }
      }
    }
  },
  mounted () {
    this.init_page()
  },
  watch: {
    showMD: {
      deep: true,
      handler (val) {
        if (val) {
          this.init_page()
        } else {
          let _self = this
          _self.editor = null
        }
      }
    }
  },
  methods: {
    // 点击上传图片成功时
    uploadImgSuccess (url) {
      var _self = this
      _self.showUploadDialog = false
      _self.editor.insertValue('![](' + url + ')')
    },
    fetchScript: function (url) {
      return new Promise((resolve) => {
        scriptjs(url, () => {
          resolve()
        })
      })
    },
    // 获取值
    getMdValue () {
      let val = this.editor.getMarkdown()
      // let val = this.editor.getPreviewedHTML()
      val = val ? encodeURIComponent(val) : val
      this.$emit('update:defaultValue', val)
    },
    // 初始化页面的方法
    init_page () {
      let _self = this
      _self.editor = null
      _self.timer = null
      _self.initData = ''
      _self.jsLoadOver = false
      _self.currentValue = _self.defaultValue ? decodeURIComponent(_self.defaultValue) : ''
      // 根据浏览器的高度来设置编辑器的高度
      if (window.screen.height > 800) {
        _self.defaultConfig.height = 660
      } else {
        _self.defaultConfig.height = 400
      }
      if (_self.disabled) {
        // 渲染不可编辑的时
        _self.initEditor_disabled()
      } else {
        // 可编辑时
        _self.initEditor()
        _self.timer = setInterval(function () {
          if (_self.editor && _self.jsLoadOver) {
            try {
              _self.editor.watch()
              window.clearInterval(_self.timer)
              _self.timer = null
            } catch (e) {}
          }
        }, 80)
      }
    },
    // 不可编辑时
    initEditor_disabled: async function () {
      let _self = this
      await this.fetchScript('/static/editorMd/js/jquery.min.js')
      await this.fetchScript('/static/editorMd/lib/marked.min.js')
      await this.fetchScript('/static/editorMd/lib/prettify.min.js')
      await this.fetchScript('/static/editorMd/lib/raphael.min.js')
      await this.fetchScript('/static/editorMd/lib/underscore.min.js')
      await this.fetchScript('/static/editorMd/lib/sequence-diagram.min.js')
      await this.fetchScript('/static/editorMd/lib/flowchart.min.js')
      await this.fetchScript('/static/editorMd/lib/jquery.flowchart.min.js')
      await this.fetchScript('/static/editorMd/editormd.min.js')
      _self.$nextTick(() => {
        _self.editor = window.editormd.markdownToHTML('editorId_show', {
          markdown: _self.currentValue,
          tocContainer: '#custom-toc-container', // 自定义 ToC 容器层
          htmlDecode: 'style,script,iframe', // you can filter tags decode
          tocm: true, // Using [TOCM]
          emoji: true,
          taskList: true,
          tex: true, // 默认不解析
          flowChart: true, // 默认不解析
          sequenceDiagram: true // 默认不解析
        })
        // 判断是否有目录,以便改变右侧目录的样式
        this.hadToc = document.getElementById('custom-toc-container').innerText
      })
    },
    // 可编辑时的样式
    initEditor: async function () {
      let _self = this
      await this.fetchScript('/static/editorMd/js/jquery.min.js')
      await this.fetchScript('/static/editorMd/lib/marked.min.js')
      await this.fetchScript('/static/editorMd/lib/prettify.min.js')
      await this.fetchScript('/static/editorMd/lib/raphael.min.js')
      await this.fetchScript('/static/editorMd/lib/underscore.min.js')
      await this.fetchScript('/static/editorMd/lib/sequence-diagram.min.js')
      await this.fetchScript('/static/editorMd/lib/flowchart.min.js')
      await this.fetchScript('/static/editorMd/lib/jquery.flowchart.min.js')
      await this.fetchScript('/static/editorMd/editormd.min.js')
      _self.jsLoadOver = true
      _self.defaultConfig.markdown = _self.currentValue
      // _self.defaultConfig.value = _self.currentValue
      _self.defaultConfig.readOnly = _self.disabled
      _self.$nextTick(() => {
        _self.editor = window.editormd('editorId', _self.defaultConfig)
        _self.editor.on('load', () => {
          setTimeout(() => { // hack bug: 一个页面多个编辑器只能初始化其中一个数据问题
            _self.initData && _self.editor.setMarkdown(_self.initData)
          }, _self.initDataDelay)
          if (!_self.disabled && _self.editor) {
            window.document.querySelector('.fa-picture-o').onclick = function () {
              _self.showUploadDialog = true
            }
          }
        })
        _self.onchange && _self.editor.on('change', () => {
          let html = _self.editor.getPreviewedHTML()
          _self.onchange({
            markdown: _self.editor.getMarkdown(),
            html: html,
            text: window.$(html).text()
          })
        })
      })
    }
  },
  destroyed () {
    let _self = this
    if (_self.timer != null) {
      window.clearInterval(_self.timer)
      _self.timer = null
    }
  }
}
</script>

<style lang = "scss">
.md_content {
  .fa {
    font-weight: normal;
    font-family: FontAwesome;
  }
}
.markdown-body,
#editorId_show{
 ul {
  list-style: circle;
  li {
    list-style: circle;
  }
 }
 ol {
  list-style: decimal;
  li {
    list-style: decimal;
  }
 }
}
#editorId .editormd-preview .markdown-body.editormd-preview-container {
  overflow: hidden;
  padding: 0 10px !important;
}
#layout {
  width: 100%;
  #sidebar {
    float: right;
    width: 360px;
    border-right: 1px solid #ddd;
    height: 700px;
    overflow-y: auto;
  }
  #editorId_show {
    width: auto;
    padding: 0;
    margin-right: 360px;
    height: 700px;
    overflow: hidden;
    overflow-y: auto;
  }
  /* 咩有目录时的样式 */
  .sildebarHidden {
    border: none !important;
    width: 0 !important;
  }
  .editorId_show_noToc {
    margin: 0 !important;
  }
}
@media (max-width:1367px) {
  #layout {
    #sidebar,
    #editorId_show {
      height: 400px;
    }
  }
}
</style>
